﻿using System;
using System.Collections.Generic;
using System.Linq;

using System.Xml.Linq;
namespace PIT.Labs.ProjectRepository.Owl2DotNet.Rdf
{
    /// <summary>
    /// Represents a class from an RDF/OWL XML Ontology
    /// </summary>
    public class RdfClass : RdfEntityBase, IClass
    {
        internal List<RdfClass> superClasses;
        internal List<IClass> subClasses;
        internal List<RdfClass> equivalentClasses;

        internal List<IIndividual> members;

        /// <summary>
        /// Create a new Class from an RDF/OWL XML Node.
        /// </summary>
        /// <param name="node">The owl:class node the class is created from.</param>
        /// <param name="o">The ontology this class is inserted into.</param>
        public RdfClass(XElement node, RdfOntology o)
            : base(node, o)
        {
            o.Insert(this);
        }

        internal RdfClass(RdfOntology o):base(o)
        {
        }

        /// <summary>
        /// Accessor to get all classes that are a subclass of the current owl:class
        /// </summary>
        public IEnumerable<IClass> SubClasses
        {
            get
            {
                if (subClasses == null)
                {
                    var k = from x in this.RdfOntology.Classes
                            where x.SuperClasses.Contains(this)
                            select x;

                    subClasses = k.ToList();

                    subClasses.AddRange(from x in this.RdfOntology.GetRestrictionClasses()
                                        where x.ParentClassUri == this.Uri.OriginalString
                                        select (IClass)x);
                }
                return subClasses;
            }
        }

        /// <summary>
        /// Accessor to get all superclasses for this owl:class
        /// </summary>
        public IEnumerable<IClass> SuperClasses
        {
            get
            {
                if (superClasses == null)
                {
                    superClasses = new List<RdfClass>();
                    RdfXmlParser.GetSuperClasses(this);
                }
                return superClasses.Select(x => (IClass)x);
            }
        }

        /// <summary>
        /// Accessor to get all owl:classes that are equivalent to this owl:class
        /// </summary>
        public IEnumerable<IClass> EquivalentClasses
        {
            get {
                if (equivalentClasses == null)
                {
                    equivalentClasses = new List<RdfClass>();
                    RdfXmlParser.GetEquivalentClasses(this);
                }

                return equivalentClasses.Select(x => (IClass)x);
            }
        }

        /// <summary>
        /// Accessor to get all owl:individuals that are a member of this owl:class
        /// </summary>
        public IEnumerable<IIndividual> Members
        {
            get {
                if (members == null)
                {
                    members = new List<IIndividual>();
                    foreach (var indi in RdfOntology.Individuals.Where(x => x.InstanceOf.Contains(this)))
                    {
                        members.Add(indi);
                    }
                }
                return members;
            }
        }       
    }
}
